package rs.fon.rapidminer.operator.learner.tree;




import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import rs.fon.rapidminer.process.annotation.Parameter;

import com.rapidminer.example.Attribute;
import com.rapidminer.example.AttributeWeights;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleSet;
import rs.fon.rapidminer.operator.learner.tree.SplittedExampleSet;
import com.rapidminer.operator.features.weighting.ChiSquaredWeighting;
import com.rapidminer.operator.IOContainer;
import com.rapidminer.operator.IOObject;
import com.rapidminer.operator.Operator;
import com.rapidminer.operator.OperatorCreationException;
import com.rapidminer.operator.OperatorDescription;
import com.rapidminer.operator.OperatorException;
import com.rapidminer.operator.UserError;
import com.rapidminer.operator.features.weighting.ChiSquaredWeighting;
import com.rapidminer.operator.learner.tree.Benefit;
import com.rapidminer.operator.preprocessing.discretization.BinDiscretization;
import com.rapidminer.parameter.UndefinedParameterError;
import com.rapidminer.parameter.Parameters;
import com.rapidminer.tools.OperatorService;
import com.rapidminer.tools.math.ContingencyTableTools;
import org.apache.commons.math.stat.inference.*;

public class RemoveInsignificantAtributesNumerical extends AbstractRemoveInsignificantAtributes {

	@Parameter(defaultValue = "0.05", maxValue = "1.0", minValue = "0.0")
	private Double Alpha_Value;

	
	
	private Parameters parameters = null;
	
	@Override
	public Object DoWork(ExampleSet splitted, List<rs.fon.rapidminer.process.Parameter> parameters, int depth, boolean [] attributesForSplitting) throws Exception
	{			
			boolean[] weights = calculateWeights(splitted, depth, attributesForSplitting,parameters);	    		    
		    return weights;	
	}
	
	public boolean[] calculateWeights(ExampleSet exampleSet, int depth,boolean [] attributesForSplitting, List<rs.fon.rapidminer.process.Parameter> parameters) throws Exception {
		
		
		for(int u=0;u<attributesForSplitting.length;u++)
			attributesForSplitting[u]=true;
		
		int k=0;
		
		
		
		Attribute label = exampleSet.getAttributes().getLabel();
		
		for(Attribute attribute : exampleSet.getAttributes())
		{
			if(!attribute.isNominal() && !attribute.equals(label))
			{			
		
				try
				{
				//boolean accept =true;
				//LinkedList<double[]> arrays = (LinkedList<double[]>)getArraysByLabel(exampleSet, attribute);
				//if(arrays.size()>1)
				double param = Double.parseDouble(parameters.get(0).getXenteredValue());
				boolean accept = TestUtils.oneWayAnovaTest(getArraysByLabel(exampleSet, attribute),param );//Hardkodovano
				attributesForSplitting[k] = accept;
				}
				catch (Exception e){}
				
			}
			k++;
		}
		
		return attributesForSplitting;	
	}
	
	private List getArraysByLabel(ExampleSet exampleSet, Attribute attribute)
	{
		
		 
		 Attribute label = exampleSet.getAttributes().getLabel();
		 LinkedList<double[]> arrays = new LinkedList();
		 LinkedList <String> labelList  = getAllCategories(exampleSet ,label);
		
		
		 int size = labelList.size();
		 
		 for (int i =0; i<size; i++)
		 {
			 String nLabel = labelList.get(i);
			 double [] arrayForF = new double [getAttributeCount(exampleSet,attribute,nLabel)];
			 Iterator<Example> reader = exampleSet.iterator(); 
		       int k=0;
		        while (reader.hasNext()) {
		            Example example = reader.next();
		            String currentValue = example.getValueAsString(label);
		            if (currentValue.equals(nLabel))
		            {
		            	Double value = Double.parseDouble(example.getValueAsString(attribute));
		            	arrayForF[k]=value.doubleValue();
		            	k++;
		            }
		              	            	
		        }
		       
		    arrays.add(arrayForF);   
		        
		 }
		 return arrays;
		
	}
	
	private int getAttributeCount(ExampleSet exampleSet, Attribute attribute, String label) // Vraca broj slogova sa odredjenom vrednoscu atributa
	{
		Iterator<Example> reader = exampleSet.iterator(); 
        int attributeCount = 0;
        while (reader.hasNext()) {
            Example example = reader.next();
            String currentValue = example.getValueAsString(exampleSet.getAttributes().getLabel());
            if (currentValue.equals(label))
              
            	attributeCount++;
           
        }
        return attributeCount;
	}
	
	
	 public  LinkedList<String> getAllCategories(ExampleSet exampleSet, Attribute attribute) {
	        LinkedList<String> allCategoryList  =  new LinkedList<String>();
	   
	       
	        Iterator<Example> reader = exampleSet.iterator();
	       
	        while (reader.hasNext()) {
	            Example example = reader.next();
	            String currentValue = example.getValueAsString(attribute);
	            if (!inList(currentValue,allCategoryList))
	                allCategoryList.add(currentValue);
	        }
	       
	        //return new SplittedExampleSet(exampleSet, partition);
	        return allCategoryList;
	    }
	   
	    public  boolean inList(String category,List<String> allCategoryList) {
	       
	        for(int i =0; i<allCategoryList.size();i++)
	        {
	            if (allCategoryList.get(i).lastIndexOf(category)!=-1)
	                return true;
	         
	        }
	       
	       return false;
	    }
	
	/*
	private long [][] getContigencyTable(ExampleSet exampleSet, Attribute attribute, int depth)
	{
		Attribute label = exampleSet.getAttributes().getLabel();
		List<String> labelCategories = null;
		List<String> attributeCategories = null;
		
		if(depth == 1)
		{
			SimpleExampleSet workingExampleSet = (SimpleExampleSet) exampleSet;
			labelCategories = workingExampleSet.getAllCategories(label);
			attributeCategories = workingExampleSet.getAllCategories(attribute);
		}
		else 
		{ 
			SplittedExampleSet workingExampleSet = (SplittedExampleSet)exampleSet;
			labelCategories = workingExampleSet.getAllCategories(label);
			attributeCategories = workingExampleSet.getAllCategories(attribute);
		}		
		
		int numberOfLabelCategories = labelCategories.size();
		int numberOfAttributeCategories = attributeCategories.size();
		
		long[][] matrix = new long[numberOfAttributeCategories][numberOfLabelCategories];
		
		for(int i = 0; i < numberOfAttributeCategories; i++)
			for(int j = 0; j < numberOfLabelCategories; j++)
			{
				matrix[i][j] = 0;
				
				for(Example example : exampleSet)
				{
				      if(labelCategories.get(j).equals(example.getNominalValue(label)) && attributeCategories.get(i).equals(example.getNominalValue(attribute)))
				    		  matrix[i][j] += 1;
				}
			}
		
		return matrix;
	}
  */
}
